﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using QYmall.Core.API.Filters;
using QYmall.Core.Common.Emum;
using QYmall.Core.Common.Extensions;
using QYmall.Core.Common.Helper;
using QYmall.Core.IServices;
using QYmall.Core.Model.Models;
using QYmall.Core.Model.ViewModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.JsonPatch;
using Microsoft.AspNetCore.Mvc;

namespace QYmall.Core.API.Controllers
{
    /// <summary>
    /// 商品信息
    /// </summary>
    [Route("admin/shop/goods")]
    [ApiController]
    public class ShopGoodsController : ControllerBase
    {
        private readonly IShopCategoryService _shopCategoryService;
        private readonly IShopGoodsService _shopGoodsService;
        private readonly IUserService _userService;
        private readonly IMapper _mapper;

        /// <summary>
        /// 依赖注入
        /// </summary>
        public ShopGoodsController(IShopCategoryService shopCategoryService, IShopGoodsService shopGoodsService, IUserService userService, IMapper mapper)
        {
            _shopCategoryService = shopCategoryService;
            _shopGoodsService = shopGoodsService;
            _userService = userService;
            _mapper = mapper;
        }

        #region 管理员调用接口==========================
        /// <summary>
        /// 根据ID获取数据
        /// 示例：/admin/shop/goods/1
        /// </summary>
        [HttpGet("{id}")]
        [Authorize]
        [AuthorizeFilter("ShopGoods", ActionType.View)]
        public async Task<IActionResult> GetById([FromRoute] long id, [FromQuery] BaseParameter param)
        {
            //检测参数是否合法
            if (!param.Fields.IsPropertyExists<ShopGoodsDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }
            //查询数据库获取实体
            var model = await _shopGoodsService.QueryAsync(x => x.Id == id, WriteRoRead.Write);
            if (model == null)
            {
                return BadRequest(ResponseMessage.Error($"数据[{id}]不存在或已删除"));
            }
            //使用AutoMapper转换成ViewModel，根据字段进行塑形
            var result = _mapper.Map<ShopGoodsDto>(model).ShapeData(param.Fields);
            return Ok(result);
        }

        /// <summary>
        /// 获取总记录数量
        /// 示例：/admin/shop/goods/view/count
        /// </summary>
        [HttpGet("view/count")]
        [Authorize]
        [AuthorizeFilter("ShopGoods", ActionType.View)]
        public async Task<IActionResult> GetCount([FromQuery] GoodsParameter searchParam)
        {
            var result = await _shopGoodsService.QueryCountAsync(
                x => (searchParam.IsLock <= 0 || x.IsLock == searchParam.IsLock)
                && (searchParam.Status <= 0 || x.Status == searchParam.Status));
            //返回成功200
            return Ok(result);
        }

        /// <summary>
        /// 获取指定数量列表
        /// 示例：/admin/shop/goods/view/10
        /// </summary>
        [HttpGet("view/{top}")]
        [Authorize]
        [AuthorizeFilter("ShopGoods", ActionType.View)]
        public async Task<IActionResult> GetList([FromRoute] int top, [FromQuery] GoodsParameter searchParam)
        {
            //检测参数是否合法
            if (searchParam.OrderBy != null
                && !searchParam.OrderBy.Replace("-", "").IsPropertyExists<ShopGoodsDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的排序参数"));
            }
            if (!searchParam.Fields.IsPropertyExists<ShopGoodsDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }

            //获取数据库列表
            var resultFrom = await _shopGoodsService.QueryListAsync(top,
                 x => (searchParam.MerchantId <= 0 || x.MerchantId == searchParam.MerchantId)
                && (searchParam.CategoryId <= 0 || x.CategoryRelations.Any(c => c.CategoryId == searchParam.CategoryId))
                && (searchParam.LabelId <= 0 || x.LabelRelations.Any(r => r.LabelId == searchParam.LabelId))
                && (searchParam.BrandId <= 0 || x.BrandId == searchParam.BrandId)
                && (searchParam.IsLock <= 0 || x.IsLock == searchParam.IsLock)
                && (searchParam.Status < 0 || x.Status == searchParam.Status)
                && (searchParam.MinPrice <= 0 || x.SellPrice >= searchParam.MinPrice)
                && (searchParam.MaxPrice <= 0 || x.SellPrice <= searchParam.MaxPrice)
                && (searchParam.StartTime == null || DateTime.Compare(x.AddTime, searchParam.StartTime.GetValueOrDefault()) >= 0)
                && (searchParam.EndTime == null || DateTime.Compare(x.AddTime, searchParam.EndTime.GetValueOrDefault()) <= 0)
                && (!searchParam.Keyword.IsNotNullOrEmpty() || (x.GoodsNo != null && x.GoodsNo.Contains(searchParam.Keyword)) || (x.Title != null && x.Title.Contains(searchParam.Keyword))),
                searchParam.OrderBy ?? "SortId,-Id");

            //映射成DTO，根据字段进行塑形
            var resultDto = _mapper.Map<IEnumerable<ShopGoodsDto>>(resultFrom).ShapeData(searchParam.Fields);
            //返回成功200
            return Ok(resultDto);
        }

        /// <summary>
        /// 获取分页列表
        /// 示例：/admin/shop/goods?pageSize=10&pageIndex=1
        /// </summary>
        [HttpGet]
        [Authorize]
        [AuthorizeFilter("ShopGoods", ActionType.View)]
        public async Task<IActionResult> GetList([FromQuery] GoodsParameter searchParam, [FromQuery] PageParamater pageParam)
        {
            //检测参数是否合法
            if (searchParam.OrderBy != null
                && !searchParam.OrderBy.Replace("-", "").IsPropertyExists<ShopGoodsDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的排序参数"));
            }
            if (!searchParam.Fields.IsPropertyExists<ShopGoodsDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }

            //获取数据列表，如果ID大于0则查询该用户下所有的列表
            var list = await _shopGoodsService.QueryPageAsync(
                pageParam.PageSize,
                pageParam.PageIndex,
                x => (searchParam.MerchantId <= 0 || x.MerchantId == searchParam.MerchantId)
                && (searchParam.CategoryId <= 0 || x.CategoryRelations.Any(c => c.CategoryId == searchParam.CategoryId))
                && (searchParam.LabelId <= 0 || x.LabelRelations.Any(r => r.LabelId == searchParam.LabelId))
                && (searchParam.BrandId <= 0 || x.BrandId == searchParam.BrandId)
                && (searchParam.Status < 0 || x.Status == searchParam.Status)
                && (searchParam.IsLock <= 0 || x.IsLock == searchParam.IsLock)
                && (searchParam.MinPrice <= 0 || x.SellPrice >= searchParam.MinPrice)
                && (searchParam.MaxPrice <= 0 || x.SellPrice <= searchParam.MaxPrice)
                && (searchParam.StartTime == null || DateTime.Compare(x.AddTime, searchParam.StartTime.GetValueOrDefault()) >= 0)
                && (searchParam.EndTime == null || DateTime.Compare(x.AddTime, searchParam.EndTime.GetValueOrDefault()) <= 0)
                && (!searchParam.Keyword.IsNotNullOrEmpty() || (x.GoodsNo != null && x.GoodsNo.Contains(searchParam.Keyword)) || (x.Title != null && x.Title.Contains(searchParam.Keyword))),
                searchParam.OrderBy ?? "SortId,-Id");

            //x-pagination
            var paginationMetadata = new
            {
                totalCount = list.TotalCount,
                pageSize = list.PageSize,
                pageIndex = list.PageIndex,
                totalPages = list.TotalPages
            };
            Response.Headers.Add("x-pagination", SerializeHelper.SerializeObject(paginationMetadata));

            //映射成DTO，根据字段进行塑形
            var resultDto = _mapper.Map<IEnumerable<ShopGoodsDto>>(list).ShapeData(searchParam.Fields);
            return Ok(resultDto);
        }

        /// <summary>
        /// 获取货品分页列表
        /// 示例：/admin/shop/goods/product?pageSize=10&pageIndex=1
        /// </summary>
        [HttpGet("product")]
        [Authorize]
        [AuthorizeFilter("ShopGoods", ActionType.View)]
        public async Task<IActionResult> GetProductList([FromQuery] GoodsParameter searchParam, [FromQuery] PageParamater pageParam)
        {
            //检测参数是否合法
            if (searchParam.OrderBy != null
                && !searchParam.OrderBy.Replace("-", "").IsPropertyExists<ShopGoodsProductListDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的排序参数"));
            }
            if (!searchParam.Fields.IsPropertyExists<ShopGoodsProductListDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }

            //获取数据列表，如果ID大于0则查询该用户下所有的列表
            var list = await _shopGoodsService.QueryProductPageAsync(
                pageParam.PageSize,
                pageParam.PageIndex,
                x => x.ShopGoods != null
                && (searchParam.MerchantId <= 0 || x.ShopGoods.MerchantId == searchParam.MerchantId)
                && (searchParam.BrandId <= 0 || x.ShopGoods.BrandId == searchParam.BrandId)
                && (searchParam.Status < 0 || x.ShopGoods.Status == searchParam.Status)
                && (searchParam.IsLock <= 0 || x.ShopGoods.IsLock == searchParam.IsLock)
                && (searchParam.StartTime == null || DateTime.Compare(x.ShopGoods.AddTime, searchParam.StartTime.GetValueOrDefault()) >= 0)
                && (searchParam.EndTime == null || DateTime.Compare(x.ShopGoods.AddTime, searchParam.EndTime.GetValueOrDefault()) <= 0)
                && (!searchParam.Keyword.IsNotNullOrEmpty() || (x.GoodsNo != null && x.GoodsNo.Contains(searchParam.Keyword)) || (x.ShopGoods.Title != null && x.ShopGoods.Title.Contains(searchParam.Keyword))),
                searchParam.OrderBy ?? "GoodsId,-Id");

            //x-pagination
            var paginationMetadata = new
            {
                totalCount = list.TotalCount,
                pageSize = list.PageSize,
                pageIndex = list.PageIndex,
                totalPages = list.TotalPages
            };
            Response.Headers.Add("x-pagination", SerializeHelper.SerializeObject(paginationMetadata));

            //映射成DTO，根据字段进行塑形
            var resultDto = _mapper.Map<IEnumerable<ShopGoodsProductListDto>>(list).ShapeData(searchParam.Fields);
            return Ok(resultDto);
        }

        /// <summary>
        /// 添加一条记录
        /// 示例：/admin/shop/goods
        /// </summary>
        [HttpPost]
        [Authorize]
        [AuthorizeFilter("ShopGoods", ActionType.Add)]
        public async Task<IActionResult> Add([FromBody] ShopGoodsEditDto modelDto)
        {
            //获取当前用户信息
            var userInfo = await _userService.GetUserAsync();
            var manageInfo = await _shopGoodsService.QueryAsync<Manager>(x => userInfo != null && x.UserId == userInfo.Id);
            if (manageInfo == null)
            {
                return BadRequest(ResponseMessage.Error($"管理员身份有误，请核实后操作"));
            }
            var result = await _shopGoodsService.AddAsync(modelDto, manageInfo.IsAudit > 0);
            return Ok(result);
        }

        /// <summary>
        /// 修改一条记录
        /// 示例：/admin/shop/goods/1
        /// </summary>
        [HttpPut("{id}")]
        [Authorize]
        [AuthorizeFilter("ShopGoods", ActionType.Edit)]
        public async Task<IActionResult> Update([FromRoute] long id, [FromBody] ShopGoodsEditDto modelDto)
        {
            //获取当前用户信息
            var userInfo = await _userService.GetUserAsync();
            var manageInfo = await _shopGoodsService.QueryAsync<Manager>(x => userInfo != null && x.UserId == userInfo.Id);
            if (manageInfo == null)
            {
                return BadRequest(ResponseMessage.Error($"管理员身份有误，请核实后操作"));
            }
            //检查数据是否存在
            if (!await _shopGoodsService.ExistsAsync<ShopGoods>(x => x.Id == id))
            {
                return BadRequest(ResponseMessage.Error($"数据[{id}]不存在或已删除"));
            }
            //调用保存方法
            var result = await _shopGoodsService.UpdateAsync(id, modelDto, manageInfo.IsAudit > 0);
            return NoContent();
        }

        /// <summary>
        /// 批量审核记录
        /// 示例：/admin/shop/goods?ids=1,2,3
        /// </summary>
        [HttpPut]
        [Authorize]
        [AuthorizeFilter("ShopGoods", ActionType.Audit)]
        public async Task<IActionResult> AuditByIds([FromQuery] string Ids)
        {
            if (Ids == null)
            {
                return BadRequest(ResponseMessage.Error("传输参数不可为空"));
            }
            //将ID列表转换成IEnumerable
            var arrIds = Ids.ToIEnumerable<long>();
            if (arrIds == null)
            {
                return BadRequest(ResponseMessage.Error("传输参数不符合规范"));
            }
            //找出符合条件的记录
            var list = await _shopGoodsService.QueryListAsync<ShopGoods>(1000, x => x.IsLock == 1 && arrIds.Contains(x.Id), WriteRoRead.Write);
            if (list == null || list.Count() == 0)
            {
                return BadRequest(ResponseMessage.Error("没有找到需要审核的记录"));
            }
            foreach (var item in list)
            {
                item.IsLock = 0;
            }
            //保存到数据库
            await _shopGoodsService.SaveAsync();

            return NoContent();
        }

        /// <summary>
        /// 局部更新一条记录
        /// 示例：/admin/shop/goods/1
        /// Body：[{"op":"replace","path":"/title","value":"new title"}]
        /// </summary>
        [HttpPatch("{id}")]
        [Authorize]
        [AuthorizeFilter("ShopGoods", ActionType.Edit)]
        public async Task<IActionResult> Update([FromRoute] long id, [FromBody] JsonPatchDocument<ShopGoodsEditDto> patchDocument)
        {
            var model = await _shopGoodsService.QueryAsync(x => x.Id == id);
            if (model == null)
            {
                return NotFound(ResponseMessage.Error($"数据[{id}]不存在或已删除"));
            }

            var modelToPatch = _mapper.Map<ShopGoodsEditDto>(model);
            patchDocument.ApplyTo(modelToPatch, ModelState);
            //验证数据是否合法
            if (!TryValidateModel(modelToPatch))
            {
                return ValidationProblem(ModelState);
            }
            //更新操作AutoMapper替我们完成，只需要调用保存即可
            _mapper.Map(modelToPatch, model);
            await _shopGoodsService.SaveAsync();

            return NoContent();
        }

        /// <summary>
        /// 删除一条记录
        /// 示例：/admin/shop/goods/1
        /// </summary>
        [HttpDelete("{id}")]
        [Authorize]
        [AuthorizeFilter("ShopGoods", ActionType.Delete)]
        public async Task<IActionResult> Delete([FromRoute] long id)
        {
            if (!await _shopGoodsService.ExistsAsync<ShopGoods>(x => x.Id == id))
            {
                return NotFound(ResponseMessage.Error($"数据{id}不存在或已删除"));
            }
            var result = await _shopGoodsService.DeleteAsync(x => x.Id == id);

            return NoContent();
        }

        /// <summary>
        /// 批量删除记录(级联数据)
        /// 示例：/admin/shop/goods?ids=1,2,3
        /// </summary>
        [HttpDelete]
        [Authorize]
        [AuthorizeFilter("ShopGoods", ActionType.Delete)]
        public async Task<IActionResult> DeleteByIds([FromQuery] string Ids)
        {
            if (Ids == null)
            {
                return BadRequest(ResponseMessage.Error("传输参数不可为空"));
            }
            //将ID列表转换成IEnumerable
            var arrIds = Ids.ToIEnumerable<long>();
            if (arrIds == null)
            {
                return BadRequest(ResponseMessage.Error("传输参数不符合规范"));
            }
            //执行批量删除操作
            await _shopGoodsService.DeleteAsync(x => arrIds.Contains(x.Id));

            return NoContent();
        }
        #endregion

        #region 商家调用接口============================
        /// <summary>
        /// 根据ID获取数据
        /// 示例：/merchant/shop/goods/1
        /// </summary>
        [HttpGet("/merchant/shop/goods/{id}")]
        [Authorize]
        public async Task<IActionResult> MerchantGetById([FromRoute] long id, [FromQuery] BaseParameter param)
        {
            //检测参数是否合法
            if (!param.Fields.IsPropertyExists<ShopGoodsDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }
            //获取登录用户ID
            int userId = await _userService.GetUserIdAsync();
            //获取商家信息
            var merchantModel = await _shopGoodsService.QueryAsync<Merchants>(x => x.UserId == userId);
            if (merchantModel == null)
            {
                return Unauthorized(ResponseMessage.Error("尚未开通商户功能，请检查重试"));
            }
            if (merchantModel.IsLock != 0)
            {
                return Unauthorized(ResponseMessage.Error("商户尚未开通，请等待审核通过"));
            }

            //查询数据库获取实体
            var model = await _shopGoodsService.QueryAsync(x => x.IsDelete == 0 && x.MerchantId == merchantModel.Id && x.Id == id, WriteRoRead.Write);
            if (model == null)
            {
                return BadRequest(ResponseMessage.Error($"数据[{id}]不存在或已删除"));
            }
            //使用AutoMapper转换成ViewModel，根据字段进行塑形
            var result = _mapper.Map<ShopGoodsDto>(model).ShapeData(param.Fields);
            return Ok(result);
        }

        /// <summary>
        /// 获取总记录数量
        /// 示例：/merchant/shop/goods/view/count
        /// </summary>
        [HttpGet("/merchant/shop/goods/view/count")]
        [Authorize]
        public async Task<IActionResult> MerchantGetCount([FromQuery] GoodsParameter searchParam)
        {
            //获取登录用户ID
            int userId = await _userService.GetUserIdAsync();
            //获取商家信息
            var merchantModel = await _shopGoodsService.QueryAsync<Merchants>(x => x.UserId == userId);
            if (merchantModel == null)
            {
                return Unauthorized(ResponseMessage.Error("尚未开通商户功能，请检查重试"));
            }
            if (merchantModel.IsLock != 0)
            {
                return Unauthorized(ResponseMessage.Error("商户尚未开通，请等待审核通过"));
            }

            var result = await _shopGoodsService.QueryCountAsync(
                x => x.IsDelete == 0
                && x.MerchantId == merchantModel.Id 
                && (searchParam.Status <= 0 || x.Status == searchParam.Status));
            //返回成功200
            return Ok(result);
        }

        /// <summary>
        /// 获取指定数量列表
        /// 示例：/merchant/shop/goods/view/10
        /// </summary>
        [HttpGet("/merchant/shop/goods/view/{top}")]
        [Authorize]
        public async Task<IActionResult> MerchantGetList([FromRoute] int top, [FromQuery] GoodsParameter searchParam)
        {
            //检测参数是否合法
            if (searchParam.OrderBy != null
                && !searchParam.OrderBy.Replace("-", "").IsPropertyExists<ShopGoodsDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的排序参数"));
            }
            if (!searchParam.Fields.IsPropertyExists<ShopGoodsDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }
            //获取登录用户ID
            int userId = await _userService.GetUserIdAsync();
            //获取商家信息
            var merchantModel = await _shopGoodsService.QueryAsync<Merchants>(x => x.UserId == userId);
            if (merchantModel == null)
            {
                return Unauthorized(ResponseMessage.Error("尚未开通商户功能，请检查重试"));
            }
            if (merchantModel.IsLock != 0)
            {
                return Unauthorized(ResponseMessage.Error("商户尚未开通，请等待审核通过"));
            }

            //获取数据库列表
            var resultFrom = await _shopGoodsService.QueryListAsync<ShopGoods>(top,
                x => x.IsDelete == 0
                && x.MerchantId == merchantModel.Id
                && (searchParam.Status < 0 || x.Status == searchParam.Status)
                && (searchParam.IsLock <= 0 || x.IsLock == searchParam.IsLock)
                && (searchParam.MinPrice <= 0 || x.SellPrice >= searchParam.MinPrice)
                && (searchParam.MaxPrice <= 0 || x.SellPrice <= searchParam.MaxPrice)
                && (searchParam.StartTime == null || DateTime.Compare(x.AddTime, searchParam.StartTime.GetValueOrDefault()) >= 0)
                && (searchParam.EndTime == null || DateTime.Compare(x.AddTime, searchParam.EndTime.GetValueOrDefault()) <= 0)
                && (!searchParam.Keyword.IsNotNullOrEmpty() || (x.GoodsNo != null && x.GoodsNo.Contains(searchParam.Keyword)) || (x.Title != null && x.Title.Contains(searchParam.Keyword))),
                searchParam.OrderBy ?? "SortId,-Id");

            //映射成DTO，根据字段进行塑形
            var resultDto = _mapper.Map<IEnumerable<ShopGoodsDto>>(resultFrom).ShapeData(searchParam.Fields);
            //返回成功200
            return Ok(resultDto);
        }

        /// <summary>
        /// 获取分页列表
        /// 示例：/merchant/shop/goods?pageSize=10&pageIndex=1
        /// </summary>
        [HttpGet("/merchant/shop/goods")]
        [Authorize]
        public async Task<IActionResult> MerchantGetList([FromQuery] GoodsParameter searchParam, [FromQuery] PageParamater pageParam)
        {
            //检测参数是否合法
            if (searchParam.OrderBy != null
                && !searchParam.OrderBy.Replace("-", "").IsPropertyExists<ShopGoodsDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的排序参数"));
            }
            if (!searchParam.Fields.IsPropertyExists<ShopGoodsDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }
            //获取登录用户ID
            int userId = await _userService.GetUserIdAsync();
            //获取商家信息
            var merchantModel = await _shopGoodsService.QueryAsync<Merchants>(x => x.UserId == userId);
            if (merchantModel == null)
            {
                return Unauthorized(ResponseMessage.Error("尚未开通商户功能，请检查重试"));
            }
            if (merchantModel.IsLock != 0)
            {
                return Unauthorized(ResponseMessage.Error("商户尚未开通，请等待审核通过"));
            }

            //获取数据列表，如果ID大于0则查询该用户下所有的列表
            var list = await _shopGoodsService.QueryPageAsync(
                pageParam.PageSize,
                pageParam.PageIndex,
                x => x.IsDelete == 0
                && x.MerchantId == merchantModel.Id
                && (searchParam.CategoryId <= 0 || x.CategoryRelations.Any(c => c.CategoryId == searchParam.CategoryId))
                && (searchParam.LabelId <= 0 || x.LabelRelations.Any(r => r.LabelId == searchParam.LabelId))
                && (searchParam.BrandId <= 0 || x.BrandId == searchParam.BrandId)
                && (searchParam.Status < 0 || x.Status == searchParam.Status)
                && (searchParam.IsLock <= 0 || x.IsLock == searchParam.IsLock)
                && (searchParam.MinPrice <= 0 || x.SellPrice >= searchParam.MinPrice)
                && (searchParam.MaxPrice <= 0 || x.SellPrice <= searchParam.MaxPrice)
                && (searchParam.StartTime == null || DateTime.Compare(x.AddTime, searchParam.StartTime.GetValueOrDefault()) >= 0)
                && (searchParam.EndTime == null || DateTime.Compare(x.AddTime, searchParam.EndTime.GetValueOrDefault()) <= 0)
                && (!searchParam.Keyword.IsNotNullOrEmpty() || (x.GoodsNo != null && x.GoodsNo.Contains(searchParam.Keyword)) || (x.Title != null && x.Title.Contains(searchParam.Keyword))),
                searchParam.OrderBy ?? "SortId,-Id");

            //x-pagination
            var paginationMetadata = new
            {
                totalCount = list.TotalCount,
                pageSize = list.PageSize,
                pageIndex = list.PageIndex,
                totalPages = list.TotalPages
            };
            Response.Headers.Add("x-pagination", SerializeHelper.SerializeObject(paginationMetadata));

            //映射成DTO，根据字段进行塑形
            var resultDto = _mapper.Map<IEnumerable<ShopGoodsDto>>(list).ShapeData(searchParam.Fields);
            return Ok(resultDto);
        }

        /// <summary>
        /// 获取货品分页列表
        /// 示例：/merchant/shop/goods/product?pageSize=10&pageIndex=1
        /// </summary>
        [HttpGet("/merchant/shop/goods/product")]
        [Authorize]
        public async Task<IActionResult> MerchantGetProductList([FromQuery] GoodsParameter searchParam, [FromQuery] PageParamater pageParam)
        {
            //检测参数是否合法
            if (searchParam.OrderBy != null
                && !searchParam.OrderBy.Replace("-", "").IsPropertyExists<ShopGoodsProductListDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的排序参数"));
            }
            if (!searchParam.Fields.IsPropertyExists<ShopGoodsProductListDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }
            //获取登录用户ID
            int userId = await _userService.GetUserIdAsync();
            //获取商家信息
            var merchantModel = await _shopGoodsService.QueryAsync<Merchants>(x => x.UserId == userId);
            if (merchantModel == null)
            {
                return Unauthorized(ResponseMessage.Error("尚未开通商户功能，请检查重试"));
            }
            if (merchantModel.IsLock != 0)
            {
                return Unauthorized(ResponseMessage.Error("商户尚未开通，请等待审核通过"));
            }

            //获取数据列表，如果ID大于0则查询该用户下所有的列表
            var list = await _shopGoodsService.QueryProductPageAsync(
                pageParam.PageSize,
                pageParam.PageIndex,
                x => x.ShopGoods != null
                && x.ShopGoods.IsDelete == 0
                && x.ShopGoods.MerchantId == merchantModel.Id
                && (searchParam.BrandId <= 0 || x.ShopGoods.BrandId == searchParam.BrandId)
                && (searchParam.Status < 0 || x.ShopGoods.Status == searchParam.Status)
                && (searchParam.IsLock <= 0 || x.ShopGoods.IsLock == searchParam.IsLock)
                && (searchParam.StartTime == null || DateTime.Compare(x.ShopGoods.AddTime, searchParam.StartTime.GetValueOrDefault()) >= 0)
                && (searchParam.EndTime == null || DateTime.Compare(x.ShopGoods.AddTime, searchParam.EndTime.GetValueOrDefault()) <= 0)
                && (!searchParam.Keyword.IsNotNullOrEmpty() || (x.GoodsNo != null && x.GoodsNo.Contains(searchParam.Keyword)) || (x.ShopGoods.Title != null && x.ShopGoods.Title!.Contains(searchParam.Keyword))),
                searchParam.OrderBy ?? "GoodsId,-Id");

            //x-pagination
            var paginationMetadata = new
            {
                totalCount = list.TotalCount,
                pageSize = list.PageSize,
                pageIndex = list.PageIndex,
                totalPages = list.TotalPages
            };
            Response.Headers.Add("x-pagination", SerializeHelper.SerializeObject(paginationMetadata));

            //映射成DTO，根据字段进行塑形
            var resultDto = _mapper.Map<IEnumerable<ShopGoodsProductListDto>>(list).ShapeData(searchParam.Fields);
            return Ok(resultDto);
        }

        /// <summary>
        /// 添加一条记录
        /// 示例：/merchant/shop/goods
        /// </summary>
        [HttpPost("/merchant/shop/goods")]
        [Authorize]
        public async Task<IActionResult> MerchantAdd([FromBody] ShopGoodsEditDto modelDto)
        {
            //获取登录用户ID
            int userId = await _userService.GetUserIdAsync();
            //获取商家信息
            var merchantModel = await _shopGoodsService.QueryAsync<Merchants>(x => x.UserId == userId);
            if (merchantModel == null)
            {
                return Unauthorized(ResponseMessage.Error("尚未开通商户功能，请检查重试"));
            }
            if (merchantModel.IsLock != 0)
            {
                return Unauthorized(ResponseMessage.Error("商户尚未开通，请等待审核通过"));
            }
            modelDto.MerchantId = merchantModel.Id;
            var result = await _shopGoodsService.AddAsync(modelDto, merchantModel.IsAudit > 0);
            return Ok(result);
        }

        /// <summary>
        /// 修改一条记录
        /// 示例：/merchant/shop/goods/1
        /// </summary>
        [HttpPut("/merchant/shop/goods/{id}")]
        [Authorize]
        public async Task<IActionResult> MerchantUpdate([FromRoute] long id, [FromBody] ShopGoodsEditDto modelDto)
        {
            //获取登录用户ID
            int userId = await _userService.GetUserIdAsync();
            //获取商家信息
            var merchantModel = await _shopGoodsService.QueryAsync<Merchants>(x => x.UserId == userId);
            if (merchantModel == null)
            {
                return Unauthorized(ResponseMessage.Error("尚未开通商户功能，请检查重试"));
            }
            if (merchantModel.IsLock != 0)
            {
                return Unauthorized(ResponseMessage.Error("商户尚未开通，请等待审核通过"));
            }
            modelDto.MerchantId = merchantModel.Id;
            //检查数据是否存在
            if (!await _shopGoodsService.ExistsAsync<ShopGoods>(x => x.IsDelete == 0 && x.MerchantId == merchantModel.Id && x.Id == id))
            {
                return BadRequest(ResponseMessage.Error($"数据[{id}]不存在或已删除"));
            }
            //调用保存方法
            var result = await _shopGoodsService.UpdateAsync(id, modelDto, merchantModel.IsAudit > 0);
            return NoContent();
        }

        /// <summary>
        /// 局部更新一条记录
        /// 示例：/merchant/shop/goods/1
        /// Body：[{"op":"replace","path":"/title","value":"new title"}]
        /// </summary>
        [HttpPatch("/merchant/shop/goods/{id}")]
        [Authorize]
        public async Task<IActionResult> MerchantUpdate([FromRoute] long id, [FromBody] JsonPatchDocument<ShopGoodsEditDto> patchDocument)
        {
            //获取登录用户ID
            int userId = await _userService.GetUserIdAsync();
            //获取商家信息
            var merchantModel = await _shopGoodsService.QueryAsync<Merchants>(x => x.UserId == userId);
            if (merchantModel == null)
            {
                return Unauthorized(ResponseMessage.Error("尚未开通商户功能，请检查重试"));
            }
            if (merchantModel.IsLock != 0)
            {
                return Unauthorized(ResponseMessage.Error("商户尚未开通，请等待审核通过"));
            }

            var model = await _shopGoodsService.QueryAsync(x => x.IsDelete == 0 && x.MerchantId == merchantModel.Id && x.Id == id);
            if (model == null)
            {
                return NotFound(ResponseMessage.Error($"数据[{id}]不存在或已删除"));
            }

            var modelToPatch = _mapper.Map<ShopGoodsEditDto>(model);
            patchDocument.ApplyTo(modelToPatch, ModelState);
            //验证数据是否合法
            if (!TryValidateModel(modelToPatch))
            {
                return ValidationProblem(ModelState);
            }
            //更新操作AutoMapper替我们完成，只需要调用保存即可
            _mapper.Map(modelToPatch, model);
            await _shopGoodsService.SaveAsync();

            return NoContent();
        }

        /// <summary>
        /// 删除一条记录
        /// 示例：/merchant/shop/goods/1
        /// </summary>
        [HttpDelete("/merchant/shop/goods/{id}")]
        [Authorize]
        public async Task<IActionResult> MerchantDelete([FromRoute] long id)
        {
            //获取登录用户ID
            int userId = await _userService.GetUserIdAsync();
            //获取商家信息
            var merchantModel = await _shopGoodsService.QueryAsync<Merchants>(x => x.UserId == userId);
            if (merchantModel == null)
            {
                return Unauthorized(ResponseMessage.Error("尚未开通商户功能，请检查重试"));
            }
            if (merchantModel.IsLock != 0)
            {
                return Unauthorized(ResponseMessage.Error("商户尚未开通，请等待审核通过"));
            }

            var model = await _shopGoodsService.QueryAsync<ShopGoods>(x => x.IsDelete == 0 && x.MerchantId == merchantModel.Id && x.Id == id);
            if (model == null)
            {
                return BadRequest(ResponseMessage.Error($"记录[{id}]不存在或已删除"));
            }
            model.IsDelete = 1; //标记删除
            //保存到数据库
            await _shopGoodsService.SaveAsync();

            return NoContent();
        }

        /// <summary>
        /// 批量删除记录(级联数据)
        /// 示例：/merchant/shop/goods?ids=1,2,3
        /// </summary>
        [HttpDelete("/merchant/shop/goods")]
        [Authorize]
        public async Task<IActionResult> MerchantDeleteByIds([FromQuery] string Ids)
        {
            if (Ids == null)
            {
                return BadRequest(ResponseMessage.Error("传输参数不可为空"));
            }
            //获取登录用户ID
            int userId = await _userService.GetUserIdAsync();
            //获取商家信息
            var merchantModel = await _shopGoodsService.QueryAsync<Merchants>(x => x.UserId == userId);
            if (merchantModel == null)
            {
                return Unauthorized(ResponseMessage.Error("尚未开通商户功能，请检查重试"));
            }
            if (merchantModel.IsLock != 0)
            {
                return Unauthorized(ResponseMessage.Error("商户尚未开通，请等待审核通过"));
            }

            //将ID列表转换成IEnumerable
            var arrIds = Ids.ToIEnumerable<long>();
            if (arrIds == null)
            {
                return BadRequest(ResponseMessage.Error("传输参数不符合规范"));
            }
            //找出符合条件的记录
            var list = await _shopGoodsService.QueryListAsync<ShopGoods>(1000, x => x.IsDelete == 0 && x.MerchantId == merchantModel.Id && arrIds.Contains(x.Id), WriteRoRead.Write);
            if (list.Count() == 0)
            {
                return BadRequest(ResponseMessage.Error("没有找到需要删除的记录"));
            }
            foreach (var item in list)
            {
                item.IsDelete = 1; //标记删除
            }
            //保存到数据库
            await _shopGoodsService.SaveAsync();

            return NoContent();
        }
        #endregion

        #region 前台调用接口============================
        /// <summary>
        /// 根据ID获取数据
        /// 示例：/client/shop/goods/1
        /// </summary>
        [HttpGet("/client/shop/goods/{id}")]
        [CachingFilter]
        public async Task<IActionResult> ClientGetById([FromRoute] long id, [FromQuery] BaseParameter searchParam)
        {
            if (!searchParam.Fields.IsPropertyExists<ShopGoodsClientDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }
            //查询数据库获取实体
            var model = await _shopGoodsService.QueryAsync(x => x.IsDelete == 0 && x.IsLock == 0 && x.Id == id);
            if (model == null)
            {
                return NotFound(ResponseMessage.Error($"数据[{id}]不存在或已删除"));
            }
            //浏览次数加一
            model.Click++;
            //保存到数据库
            await _shopGoodsService.UpdateClickAsync(model);
            //使用AutoMapper转换成ViewModel，根据字段进行塑形
            var result = _mapper.Map<ShopGoodsClientDto>(model).ShapeData(searchParam.Fields);
            return Ok(result);
        }

        /// <summary>
        /// 获取指定数量列表
        /// 示例：/client/shop/goods/view/10
        /// </summary>
        [HttpGet("/client/shop/goods/view/{top}")]
        [CachingFilter]
        public async Task<IActionResult> ClientGetList([FromRoute] int top, [FromQuery] GoodsParameter searchParam)
        {
            if (searchParam.OrderBy != null
                && !searchParam.OrderBy.Replace("-", "").IsPropertyExists<ShopGoodsDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的排序参数"));
            }
            if (!searchParam.Fields.IsPropertyExists<ShopGoodsClientDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }

            //获取数据库列表
            var resultFrom = await _shopGoodsService.QueryListAsync(top,
                x => x.IsDelete == 0
                && x.IsLock == 0
                && x.Status == 0
                && (searchParam.MerchantId <= 0 || x.MerchantId == searchParam.MerchantId)
                && (searchParam.CategoryId <= 0 || x.CategoryRelations.Any(c => c.CategoryId == searchParam.CategoryId))
                && (searchParam.LabelId <= 0 || x.LabelRelations.Any(r => r.LabelId == searchParam.LabelId))
                && (searchParam.BrandId <= 0 || x.BrandId == searchParam.BrandId)
                && (searchParam.MinPrice <= 0 || x.SellPrice >= searchParam.MinPrice)
                && (searchParam.MaxPrice <= 0 || x.SellPrice <= searchParam.MaxPrice)
                && (searchParam.StartTime == null || DateTime.Compare(x.AddTime, searchParam.StartTime.GetValueOrDefault()) >= 0)
                && (searchParam.EndTime == null || DateTime.Compare(x.AddTime, searchParam.EndTime.GetValueOrDefault()) <= 0)
                && (!searchParam.Keyword.IsNotNullOrEmpty() || (x.GoodsNo != null && x.GoodsNo.Contains(searchParam.Keyword)) || (x.Title != null && x.Title.Contains(searchParam.Keyword))),
                searchParam.OrderBy ?? "SortId,-Id");

            //映射成DTO，根据字段进行塑形
            var resultDto = _mapper.Map<IEnumerable<ShopGoodsClientDto>>(resultFrom).ShapeData(searchParam.Fields);
            //返回成功200
            return Ok(resultDto);
        }

        /// <summary>
        /// 获取分页列表
        /// 示例：/client/shop/goods?pageSize=10&pageIndex=1
        /// </summary>
        [HttpGet("/client/shop/goods")]
        [CachingFilter]
        public async Task<IActionResult> ClientGetList([FromQuery] GoodsParameter searchParam, [FromQuery] PageParamater pageParam)
        {
            //检测参数是否合法
            if (searchParam.OrderBy != null
                && !searchParam.OrderBy.Replace("-", "").IsPropertyExists<ShopGoodsDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的排序参数"));
            }
            if (!searchParam.Fields.IsPropertyExists<ShopGoodsClientDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }

            //获取数据列表，如果ID大于0则查询该用户下所有的列表
            var list = await _shopGoodsService.QueryPageAsync(
                pageParam.PageSize,
                pageParam.PageIndex,
                x => x.IsDelete == 0
                && x.IsLock == 0
                && x.Status == 0
                && (searchParam.MerchantId <= 0 || x.MerchantId == searchParam.MerchantId)
                && (searchParam.CategoryId <= 0 || x.CategoryRelations.Any(c => c.CategoryId == searchParam.CategoryId))
                && (searchParam.LabelId <= 0 || x.LabelRelations.Any(r => r.LabelId == searchParam.LabelId))
                && (searchParam.BrandId <= 0 || x.BrandId == searchParam.BrandId)
                && (searchParam.MinPrice <= 0 || x.SellPrice >= searchParam.MinPrice)
                && (searchParam.MaxPrice <= 0 || x.SellPrice <= searchParam.MaxPrice)
                && (searchParam.StartTime == null || DateTime.Compare(x.AddTime, searchParam.StartTime.GetValueOrDefault()) >= 0)
                && (searchParam.EndTime == null || DateTime.Compare(x.AddTime, searchParam.EndTime.GetValueOrDefault()) <= 0)
                && (!searchParam.Keyword.IsNotNullOrEmpty() || (x.GoodsNo != null && x.GoodsNo.Contains(searchParam.Keyword)) || (x.Title != null && x.Title.Contains(searchParam.Keyword))),
                searchParam.OrderBy ?? "SortId,-Id");

            //x-pagination
            var paginationMetadata = new
            {
                totalCount = list.TotalCount,
                pageSize = list.PageSize,
                pageIndex = list.PageIndex,
                totalPages = list.TotalPages
            };
            Response.Headers.Add("x-pagination", SerializeHelper.SerializeObject(paginationMetadata));

            //映射成DTO，根据字段进行塑形
            var resultDto = _mapper.Map<IEnumerable<ShopGoodsClientDto>>(list).ShapeData(searchParam.Fields);
            return Ok(resultDto);
        }

        /// <summary>
        /// 获取分类商品指定数量列表
        /// 示例：/client/shop/goods/view/10/2
        /// </summary>
        [HttpGet("/client/shop/goods/view/{categoryTop}/{goodsTop}")]
        [CachingFilter]
        public async Task<IActionResult> ClientGetCategoryList([FromRoute] int categoryTop, int goodsTop, [FromQuery] GoodsParameter searchParam)
        {
            if (!searchParam.Fields.IsPropertyExists<ShopCategoryGoodsClientDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }
            //获取前几条分类,最多获取前10个分类
            if (categoryTop > 10) categoryTop = 10;
            if(goodsTop > 10) goodsTop = 10;

            var result = await _shopCategoryService.QueryGoodsListAsync(categoryTop, goodsTop, 0, x => x.IsDelete == 0 && x.IsLock == 0 && x.Status == 0, searchParam.OrderBy ?? "SortId,Id");
            return Ok(result);
        }
        #endregion

        #region 我的酒库
        /// <summary>
        /// 获取分页列表
        /// 示例：/account/member/warehouse?pageSize=10&pageIndex=1
        /// </summary>
        [HttpGet("/account/member/warehouse")]
        [Authorize]
        public async Task<IActionResult> MerchantGoodsList([FromQuery] GoodsParameter searchParam, [FromQuery] PageParamater pageParam)
        {
            //检测参数是否合法
            if (searchParam.OrderBy != null
                && !searchParam.OrderBy.Replace("-", "").IsPropertyExists<ShopGoodsDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的排序参数"));
            }
            if (!searchParam.Fields.IsPropertyExists<ShopGoodsDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }
            //获取登录用户ID
            int userId = await _userService.GetUserIdAsync();
            //获取商家信息
            var merchantModel = await _shopGoodsService.QueryAsync<Merchants>(x => x.UserId == userId);
            if (merchantModel == null)
            {
                return Unauthorized(ResponseMessage.Error("尚未开通商户功能，请检查重试"));
            }
            if (merchantModel.IsLock != 0)
            {
                return Unauthorized(ResponseMessage.Error("商户尚未开通，请等待审核通过"));
            }

            //获取数据列表，如果ID大于0则查询该用户下所有的列表
            var list = await _shopGoodsService.QueryPageAsync(
                pageParam.PageSize,
                pageParam.PageIndex,
                x => x.IsDelete == 0
                && x.MerchantId == merchantModel.Id
                && (searchParam.CategoryId <= 0 || x.CategoryRelations.Any(c => c.CategoryId == searchParam.CategoryId))
                && (searchParam.LabelId <= 0 || x.LabelRelations.Any(r => r.LabelId == searchParam.LabelId))
                && (searchParam.BrandId <= 0 || x.BrandId == searchParam.BrandId)
                && (searchParam.Status < 0 || x.Status == searchParam.Status)
                && (searchParam.IsLock <= 0 || x.IsLock == searchParam.IsLock)
                && (searchParam.MinPrice <= 0 || x.SellPrice >= searchParam.MinPrice)
                && (searchParam.MaxPrice <= 0 || x.SellPrice <= searchParam.MaxPrice)
                && (searchParam.StartTime == null || DateTime.Compare(x.AddTime, searchParam.StartTime.GetValueOrDefault()) >= 0)
                && (searchParam.EndTime == null || DateTime.Compare(x.AddTime, searchParam.EndTime.GetValueOrDefault()) <= 0)
                && (!searchParam.Keyword.IsNotNullOrEmpty() || (x.GoodsNo != null && x.GoodsNo.Contains(searchParam.Keyword)) || (x.Title != null && x.Title.Contains(searchParam.Keyword))),
                searchParam.OrderBy ?? "SortId,-Id");

            //x-pagination
            var paginationMetadata = new
            {
                totalCount = list.TotalCount,
                pageSize = list.PageSize,
                pageIndex = list.PageIndex,
                totalPages = list.TotalPages
            };
            Response.Headers.Add("x-pagination", SerializeHelper.SerializeObject(paginationMetadata));

            //映射成DTO，根据字段进行塑形
            var resultDto = _mapper.Map<IEnumerable<ShopGoodsDto>>(list).ShapeData(searchParam.Fields);
            return Ok(resultDto);
        }

        #endregion

    }
}
